package dao

import (
	"apedge/pkg/protocol"
	"fmt"
	"time"

	"github.com/jinzhu/gorm"
)

const (
	TableApedgeNode string = "t_apedge_node"
)

type ApedgeNode struct {
	ID                      int64      `gorm:"primary_key" json:"id"`
	OrgId                   int64      `gorm:"not null" json:"orgId"`
	GroupId                 int64      `gorm:"not null" json:"groupId"`
	UserId                  int64      `gorm:"not null" json:"userId"`
	UserName                string     `gorm:"not null;describe:'创建人'" json:"userName"`
	NodeName                string     `gorm:"unique;not null;describe:'节点名字'" json:"nodeName"`
	NodeId                  string     `gorm:"unique;not null;describe:'节点唯一ID'" json:"nodeId"`
	Describe                string     `gorm:"describe:'节点描述'" json:"describe"`
	NodeType                string     `gorm:"describe:'节点类型'" json:"nodeType"`
	Arch                    string     `gorm:"describe:'节点架构'" json:"arch"`
	Cpu                     int64      `gorm:"describe:'cpu'" json:"cpu"`
	Mem                     int64      `gorm:"describe:'内存'" json:"mem"`
	Status                  string     `gorm:"not null;describe:'状态'" json:"status"`
	Roles                   string     `gorm:"describe:'角色'" json:"roles"`
	ServiceNum              int64      `gorm:"describe:'服务数量'" json:"serviceNum"`
	ContainerRuntimeVersion string     `gorm:"describe:'容器运行时版本'" json:"containerRuntimeVersion"`
	OsImage                 string     `gorm:"describe:'镜像名'" json:"osImage"`
	DeviceSeries            string     `gorm:"describe:'设备序列'" json:"deviceSeries"`
	DeviceSpec              string     `gorm:"describe:'设备规格'" json:"deviceSpec"`
	CreatedAt               *time.Time `gorm:"not null" json:"createdAt"`
	UpdatedAt               *time.Time `gorm:"not null" json:"updatedAt"`
	DeletedAt               *time.Time `gorm:"default null" json:"deletedAt"`
}

func (ApedgeNode) TableName() string {
	return TableApedgeNode
}

func (t *ApedgeNode) Save(tx *gorm.DB) error {
	return tx.Save(t).Error
}

func (t *ApedgeNode) GetNodeByName(tx *gorm.DB) (*ApedgeNode, error) {
	var item ApedgeNode

	err := tx.Where("node_name = ?", t.NodeName).Find(&item).Error
	if err != nil {
		return nil, err
	}
	return &item, err
}

func (t *ApedgeNode) GetNodeNumByName(tx *gorm.DB) (int64, error) {
	var count int64

	err := tx.Model(&ApedgeNode{}).Where("node_name = ?", t.NodeName).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}

func (t *ApedgeNode) GetNodeByNodeId(tx *gorm.DB) (*ApedgeNode, error) {
	var item ApedgeNode

	err := tx.Where("node_id = ?", t.NodeId).Find(&item).Error
	if err != nil {
		return nil, err
	}
	return &item, err
}

func (t *ApedgeNode) GetNodeNumByNodeId(tx *gorm.DB) (int64, error) {
	var count int64

	err := tx.Model(&ApedgeNode{}).Where("node_id = ?", t.NodeId).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}

func (t *ApedgeNode) GetNodeList(tx *gorm.DB, pageNum int64, pageSize int64, nodeName string, sort string, status string, deviceSeries []string, userInfo *protocol.UserInfoAAA) ([]ApedgeNode, int64, error) {
	var list []ApedgeNode
	var err error
	var count int64

	offset := (pageNum - 1) * pageSize

	query := tx.Table(t.TableName())
	// 按组织筛选
	query = query.Where("group_id = ?", userInfo.GroupId)

	// node_name 模糊搜索
	if nodeName != "" {
		nodeName = "%" + nodeName + "%"
		query = query.Where("node_name LIKE ?", nodeName)
	}

	// 按条件筛选
	if status != "" {
		query = query.Where("status = ?", status)
	}

	if len(deviceSeries) != 0 {
		query = query.Where("device_series IN (?)", deviceSeries)
	}
	// 获取总数量
	err = query.Count(&count).Error
	if err != nil {
		return nil, 0, err
	}

	sortMap := ParseSort(sort)
	if _, ok := sortMap["status"]; !ok {
		sortMap["status"] = "desc"
	}
	fmt.Printf("sortMap: %s \n", sortMap)
	for k, v := range sortMap {
		order := fmt.Sprintf("%s %s", k, v)
		query = query.Order(order)
	}

	err = query.Limit(pageSize).Offset(offset).Find(&list).Error
	if err != nil {
		return nil, 0, err
	}

	return list, count, err
}

func (t *ApedgeNode) DeleteByNodeId(tx *gorm.DB) error {
	return tx.Where("node_id = ?", t.NodeId).Unscoped().Delete(&ApedgeNode{}).Error
}

func (t *ApedgeNode) UpdateByNodeId(tx *gorm.DB, data interface{}) error {

	err := tx.Model(&ApedgeNode{}).Where("node_id = ?", t.NodeId).Updates(data).Error

	if err != nil {
		return err
	}
	return nil
}

func (t *ApedgeNode) GetNodeListByNodeIds(tx *gorm.DB, nodeIds []string) ([]ApedgeNode, error) {
	var items []ApedgeNode

	err := tx.Where("node_id IN (?)", nodeIds).Find(&items).Error
	if err != nil {
		return nil, err
	}
	return items, err
}
